package com.pascualabs.android.lwsnowing;

import java.util.Random;

import org.andengine.engine.camera.Camera;
import org.andengine.engine.options.EngineOptions;
import org.andengine.engine.options.ScreenOrientation;
import org.andengine.engine.options.resolutionpolicy.RatioResolutionPolicy;
import org.andengine.entity.particle.BatchedSpriteParticleSystem;
import org.andengine.entity.particle.emitter.PointParticleEmitter;
import org.andengine.entity.particle.initializer.AccelerationParticleInitializer;
import org.andengine.entity.particle.initializer.BlendFunctionParticleInitializer;
import org.andengine.entity.particle.initializer.GravityParticleInitializer;
import org.andengine.entity.particle.initializer.RotationParticleInitializer;
import org.andengine.entity.particle.initializer.VelocityParticleInitializer;
import org.andengine.entity.particle.modifier.AlphaParticleModifier;
import org.andengine.entity.particle.modifier.ExpireParticleInitializer;
import org.andengine.entity.scene.Scene;
import org.andengine.entity.scene.background.SpriteBackground;
import org.andengine.entity.sprite.Sprite;
import org.andengine.entity.sprite.UncoloredSprite;
import org.andengine.extension.ui.livewallpaper.BaseLiveWallpaperService;
import org.andengine.opengl.texture.TextureOptions;
import org.andengine.opengl.texture.atlas.bitmap.BitmapTextureAtlas;
import org.andengine.opengl.texture.atlas.bitmap.BitmapTextureAtlasTextureRegionFactory;
import org.andengine.opengl.texture.region.ITextureRegion;
import org.andengine.opengl.texture.region.TextureRegion;
import org.andengine.input.sensor.acceleration.AccelerationData;
import org.andengine.input.sensor.acceleration.IAccelerationListener;
import android.content.SharedPreferences;
import android.opengl.GLES20;
import android.view.Display;
import android.view.Surface;
import android.view.WindowManager;

public class BaseGame extends BaseLiveWallpaperService implements
		IAccelerationListener,
		SharedPreferences.OnSharedPreferenceChangeListener {

	// ===========================================================
	// Constants
	// ===========================================================

	public static final String SHARED_PREFS_NAME = "preferences";
	private static int CAMERA_WIDTH = 480;
	private static int CAMERA_HEIGHT = 800;

	// ===========================================================
	// Fields
	// ===========================================================
	Scene scene = new Scene();
	private ITextureRegion mFondoNavidadTextureRegion;
	private ITextureRegion mFondoNavidadTextureRegion2;

	private TextureRegion mParticleTextureRegion;

	private BitmapTextureAtlas taFondo;
	private BitmapTextureAtlas taParticle;

	private SpriteBackground bg1;
	private SpriteBackground bg2;

	Random rnd = new Random();
	Display display;
	RatioResolutionPolicy ratio;

	private int rotation;
	private float centerX;
	private float centerY;

	private BitmapTextureAtlas taFondo2;
	private Camera camera;

	// PARTICLE SYSTEM//
	private VelocityParticleInitializer<UncoloredSprite> mVelocityParticleInitializer;
	// Set the max and min rates that particles are generated per second
	final int mParticleMinRate = 1;
	final int mParticleMaxRate = 2;
	// Set a variable for the max particles in the system.
	final int mParticleMax = 50;

	@Override
	public EngineOptions onCreateEngineOptions() {
		// WindowManager windowManager = (WindowManager)
		// getSystemService(WINDOW_SERVICE);
		display = ((WindowManager) getSystemService(WINDOW_SERVICE))
				.getDefaultDisplay();

		camera = new Camera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT);
		// camera.setResizeOnSurfaceSizeChanged(true);
		EngineOptions options = new EngineOptions(true,
				ScreenOrientation.PORTRAIT_FIXED, new RatioResolutionPolicy(
						CAMERA_WIDTH, CAMERA_HEIGHT), camera);
		return options;
	}

	@Override
	public void onCreateResources(
			OnCreateResourcesCallback pOnCreateResourcesCallback)
			throws Exception {
		loadGfx();
		this.enableAccelerationSensor(this);
		pOnCreateResourcesCallback.onCreateResourcesFinished();
		// TODO Auto-generated method stub

	}

	private void loadGfx() {

		BitmapTextureAtlasTextureRegionFactory.setAssetBasePath("gfx/");

		this.taFondo = new BitmapTextureAtlas(getTextureManager(), 2048, 2048);
		this.taFondo2 = new BitmapTextureAtlas(getTextureManager(), 2048, 2048);
		this.mFondoNavidadTextureRegion = BitmapTextureAtlasTextureRegionFactory
				.createFromAsset(taFondo, this, "forest_480x800.png", 0, 0);
		this.mFondoNavidadTextureRegion2 = BitmapTextureAtlasTextureRegionFactory
				.createFromAsset(taFondo2, this, "forest_800x480.png", 0, 0);

		this.taParticle = new BitmapTextureAtlas(this.getTextureManager(), 32,
				32, TextureOptions.BILINEAR_PREMULTIPLYALPHA);
		this.mParticleTextureRegion = BitmapTextureAtlasTextureRegionFactory
				.createFromAsset(this.taParticle, this, "particle_point.png",
						0, 0);

		this.taParticle.load();
		this.taFondo.load();
		this.taFondo2.load();

	}

	@Override
	public void onCreateScene(OnCreateSceneCallback pOnCreateSceneCallback)
			throws Exception {

		this.scene = new Scene();

		/* Fondo de pantalla */
//		final float centerX = (CAMERA_WIDTH - mFondoNavidadTextureRegion
//				.getWidth()) / 2;
//		final float centerY = (CAMERA_HEIGHT - mFondoNavidadTextureRegion
//				.getHeight()) / 2;
//		bg1 = new SpriteBackground(new Sprite(centerX, centerY,
//				this.mFondoNavidadTextureRegion,
//				this.getVertexBufferObjectManager()));
//		this.scene.setBackground(bg1);
		updateBackground();
		
		createParticleSistem(CAMERA_WIDTH / 4, 0);
		createParticleSistem(CAMERA_WIDTH / 4 * 3, 0);

		pOnCreateSceneCallback.onCreateSceneFinished(this.scene);

	}

	private void createParticleSistem(int mParticleX, int mParticleY) {

		final BatchedSpriteParticleSystem particleSystem = new BatchedSpriteParticleSystem(
				new PointParticleEmitter(mParticleX, mParticleY),
				mParticleMinRate, mParticleMaxRate, mParticleMax,
				this.mParticleTextureRegion,
				this.getVertexBufferObjectManager());

		particleSystem
				.addParticleInitializer(new BlendFunctionParticleInitializer<UncoloredSprite>(
						GLES20.GL_SRC_ALPHA, GLES20.GL_ONE));
		// set initial velocity
		this.mVelocityParticleInitializer = new VelocityParticleInitializer<UncoloredSprite>(
				-100, 100, 20, 190);
		particleSystem
				.addParticleInitializer(this.mVelocityParticleInitializer);

		// add gravity so the particles fall downward
		particleSystem
				.addParticleInitializer(new GravityParticleInitializer<UncoloredSprite>());
		// add acceleration so particles float
		particleSystem
				.addParticleInitializer(new AccelerationParticleInitializer<UncoloredSprite>(
						0, -7));
		// add a rotation to particles
		particleSystem
				.addParticleInitializer(new RotationParticleInitializer<UncoloredSprite>(
						0.0f, 90.0f));
		// have particles expire after 40
		particleSystem
				.addParticleInitializer(new ExpireParticleInitializer<UncoloredSprite>(
						40.0f));

		particleSystem
				.addParticleModifier(new AlphaParticleModifier<UncoloredSprite>(
						0.0f, 10.f, 0.25f, 1.0f));
		particleSystem
				.addParticleModifier(new AlphaParticleModifier<UncoloredSprite>(
						25.0f, 40.0f, 1.0f, 0.0f));

		scene.attachChild(particleSystem);

	}

	@Override
	public void onPopulateScene(Scene pScene,
			OnPopulateSceneCallback pOnPopulateSceneCallback) throws Exception {
		pOnPopulateSceneCallback.onPopulateSceneFinished();
	}

	@Override
	public void onAccelerationAccuracyChanged(AccelerationData pAccelerationData) {
	}

	@Override
	public void onAccelerationChanged(AccelerationData pAccelerationData) {
		updateBackground();
	}

	@Override
	public void onSharedPreferenceChanged(SharedPreferences arg0, String arg1) {
		// TODO Auto-generated method stub

	}
	
	public void updateBackground(){
		rotation = display.getRotation();
		display = ((WindowManager) getSystemService(WINDOW_SERVICE))
				.getDefaultDisplay();

		if (rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270) {
			centerX = (CAMERA_HEIGHT - mFondoNavidadTextureRegion2.getWidth()) / 2;
			centerY = (CAMERA_WIDTH - mFondoNavidadTextureRegion2.getHeight()) / 2;
			bg2 = new SpriteBackground(new Sprite(centerX, centerY,
					this.mFondoNavidadTextureRegion2,
					this.getVertexBufferObjectManager()));
			this.scene.setBackground(bg2);
			camera.set(0, 0, CAMERA_HEIGHT, CAMERA_WIDTH);

		} else if (rotation == Surface.ROTATION_0
				|| rotation == Surface.ROTATION_180) {

			centerX = (CAMERA_WIDTH - mFondoNavidadTextureRegion.getWidth()) / 2;
			centerY = (CAMERA_HEIGHT - mFondoNavidadTextureRegion.getHeight()) / 2;
			bg1 = new SpriteBackground(new Sprite(centerX, centerY,
					this.mFondoNavidadTextureRegion,
					this.getVertexBufferObjectManager()));
			this.scene.setBackground(bg1);
			camera.set(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT);
		}
	}

}
